package cn.zynworld.fansafe.jwt.factory;

import cn.zynworld.fansafe.common.utils.CodecUtils;
import cn.zynworld.fansafe.common.utils.JsonUtils;
import cn.zynworld.fansafe.jwt.core.JwtBean;

import java.util.HashMap;
import java.util.Map;

/**
 * @auther Buynow Zhao
 * @create 2018/6/1
 * 用于生成JwtBean
 */
public class JwtBeanFactory {

	private final String SECRET;

	// 公共的头部及荷载 所有该工厂对象生产的JwtBean 继承这些公共数据
	// 仅仅限制为字符串
	private Map<String,String> commonHeadMap = new HashMap<String, String>();
	private Map<String,String> commonPlayloadMap = new HashMap<String, String>();

	// 公共插槽检测方法 在该仓库检测生成jwtBean 必须经过这些插槽检测方法过滤
	private JwtCheckSlotFunctionGroup commonSlotFunctionGroup = new JwtCheckSlotFunctionGroup();

	public JwtBeanFactory(String secret) {
		this.SECRET = secret;
	}

	/**
	 * 通过jwt串 解码后获取JwtBean
	 * 若非合法jwt 将返回null
	 * @param jwt
	 * @return
	 */
	public JwtBean getJwtBean(String jwt,JwtCheckSlotFunctionGroup slotFunctionGroup){
		if (jwt == null){
			return null;
		}
		String[] jwts = jwt.split("\\.");
		if (jwts.length != 3){
			return null;
		}
		//验证
		String signature = CodecUtils.getSHA256Str(jwts[0] + "." + jwts[1] + this.SECRET);
		if (!jwts[2].equals(signature)){
			return null;
		}
		//验证成功 构建jwtBean
		JwtBean jwtBean = null;
		try{
			jwtBean = this.newJwtBean();
			jwtBean.setHeadMap( JsonUtils.jsonToMap(CodecUtils.decodeBase64(jwts[0])));
			jwtBean.setPlayloadMap( JsonUtils.jsonToMap(CodecUtils.decodeBase64(jwts[1])));
		}catch (Exception e){
			return null;
		}

		// 公共插槽检测方法 过滤
		if (!commonSlotFunctionGroup.isEmpty()) {
			for (JwtCheckSlotFunction checkFun :
					commonSlotFunctionGroup.getSlotFunctionList()) {
				if (checkFun.check(jwtBean) == false) {
					// 检测失败未通过
					return null;
				}
			}
		}
		// 非公共的插槽检测方法 过滤
		if (slotFunctionGroup != null && !slotFunctionGroup.isEmpty()) {
			for (JwtCheckSlotFunction checkFun :
					slotFunctionGroup.getSlotFunctionList()) {
				if (checkFun.check(jwtBean) == false) {
					// 检测失败未通过
					return null;
				}
			}
		}
		return jwtBean;
	}

	public JwtBean getJwtBean(String jwt) {
		return getJwtBean(jwt, null);
	}


	/**
	 * 为jwt仓库添加公共头信息
	 * 安全起见，只允许添加字符串
	 */
	public void addCommonHead(String key, String value){
		commonHeadMap.put(key,value);
	}

	/**
	 * 为jwt仓库添加公共荷载信息
	 * 安全起见，只允许添加字符串
	 */
	public void addCommonPlayload(String key, String value){
		commonPlayloadMap.put(key,value);
	}

	public void addSlotFunction(JwtCheckSlotFunction checkSlotFunction) {
		commonSlotFunctionGroup.addSlotFunction(checkSlotFunction);
	}

	/**
	 * 创建一个新的JwtBean
	 * @return
	 */
	public JwtBean newJwtBean() {
		JwtBean jwtBean = new JwtBean(this.SECRET);
		// 添加公共数据
		jwtBean.getHeadMap().putAll(this.commonHeadMap);
		jwtBean.getPlayloadMap().putAll(this.commonPlayloadMap);
		return jwtBean;
	}







}
